package com.oig.sys.query;

import cn.hutool.core.collection.CollectionUtil;
import com.oig.common.module.SysPageInfo;
import com.oig.sys.query.support.module.SqlAndParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysCommQueryServiceImpl implements SysCommQueryService {

    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    public SysCommQueryServiceImpl(NamedParameterJdbcTemplate namedParameterJdbcTemplate){
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate ;
    }


    @Override
    public SysPageInfo<Map<String, Object>> queryForPage(String jsonText, SysCommQueryReq queryReq){
        log.info("query json:{}, query condition:{}", jsonText, queryReq);
        QuerySqlBuilder sqlBuilder = new QuerySqlBuilder();
        SqlAndParams sqlAndParams = sqlBuilder.covertSql(jsonText, queryReq);
        log.info("query sql:{}", sqlAndParams.getSql());
        log.info("count sql:{}", sqlAndParams.getCountSql());
        List<Map<String, Object>> res = namedParameterJdbcTemplate.queryForList(sqlAndParams.getSql(), sqlAndParams.getParams()) ;
        Long total = namedParameterJdbcTemplate.queryForObject(sqlAndParams.getCountSql(), sqlAndParams.getParams(), Long.class);
        if (total==null) total = 0L ;
        int pageNo ;
        if (queryReq.getPage().size()==3){
            pageNo = queryReq.getPage().get(2) ;
        } else {
            pageNo = (queryReq.getPage().get(0)+queryReq.getPage().get(1))/queryReq.getPage().get(1) ;
        }
        SysPageInfo<Map<String, Object>> pageInfo = new SysPageInfo<>(pageNo, queryReq.getPage().get(1), total) ;
        pageInfo.setList(this.dealExcludeProperty(queryReq, res));
        return pageInfo;
    }

    //字段权限过滤，没有权限的字段从查询返回的map里移除
    private List<Map<String,Object>> dealExcludeProperty(SysCommQueryReq queryReq,List<Map<String, Object>> res){
        if (CollectionUtil.isNotEmpty(queryReq.getColumnPropertyList())){
            List<Map<String, Object>> rtnList = new ArrayList<>();
            for (Map<String, Object> reMap : res) {
                Map<String,Object> exMap = reMap.entrySet().stream().filter(map->queryReq.getColumnPropertyList().contains(map.getKey()))
                        .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
                rtnList.add(exMap);
            }
            return rtnList;
        }
        return res;
    }

    @Override
    public List<Map<String, Object>> queryForList(String jsonText, SysCommQueryReq queryReq) {
        log.info(" query for list json:{} --cond:{}",jsonText, queryReq);
        QuerySqlBuilder sqlBuilder = new QuerySqlBuilder();
        SqlAndParams sqlAndParams = sqlBuilder.covertOnlyQuerySql(jsonText, queryReq);
        log.info("query sql:{}", sqlAndParams.getSql());
        List<Map<String, Object>> res = namedParameterJdbcTemplate.queryForList(sqlAndParams.getSql(), sqlAndParams.getParams()) ;
        return this.dealExcludeProperty(queryReq, res) ;
    }


    /**
     * 按DTO返回
     * @param jsonText 查询配置
     * @param queryReq 查询请求参数
     * @param tClass dto class
     * @param <T>  dto对象
     */
    @Override
    public <T> SysPageInfo<T> pageList(String jsonText, SysCommQueryReq queryReq, Class<T> tClass) {
        log.info("page query- json:{} --cond:{}",jsonText, queryReq);
        QuerySqlBuilder sqlBuilder = new QuerySqlBuilder();
        SqlAndParams sqlAndParams = sqlBuilder.covertSql(jsonText, queryReq);
        log.info("page query- sql:{}", sqlAndParams.getSql());
        log.info("count- sql:{}", sqlAndParams.getCountSql());
        List<T> res = namedParameterJdbcTemplate.query(sqlAndParams.getSql(), sqlAndParams.getParams(), new BeanPropertyRowMapper<>(tClass)) ;
        Long total = namedParameterJdbcTemplate.queryForObject(sqlAndParams.getCountSql(), sqlAndParams.getParams(), Long.class);
        if (total == null) {
            total = 0L ;
        }
        int pageNo = (queryReq.getPage().get(0)+queryReq.getPage().get(1))/queryReq.getPage().get(1) ;
        SysPageInfo<T> pageInfo = new SysPageInfo<>(pageNo, queryReq.getPage().get(1), total) ;
        pageInfo.setList(res);
        return pageInfo;
    }

    @Override
    public <T> List<T> list(String jsonText, SysCommQueryReq queryReq, Class<T> tClass) {
        log.info("query- json:{} --cond:{}",jsonText, queryReq);
        QuerySqlBuilder sqlBuilder = new QuerySqlBuilder();
        SqlAndParams sqlAndParams = sqlBuilder.covertOnlyQuerySql(jsonText, queryReq);
        log.info("query- sql:{}", sqlAndParams.getSql());
        return namedParameterJdbcTemplate.query(sqlAndParams.getSql(), sqlAndParams.getParams(), new BeanPropertyRowMapper<>(tClass)) ;
    }

}
